/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/




#if !defined(AFX_PGLPIE_H__8D63690A_E25F_4D15_B3C4_F7BFBDA15B34__INCLUDED_)
#define AFX_PGLPIE_H__8D63690A_E25F_4D15_B3C4_F7BFBDA15B34__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <pgl/core/PGLObject.h>
#include <pgl/core/PGLPieData.h>
#include <pgl/core/PGLText.h>
#include <pgl/core/PGLLegend.h>

/*!
	\defgroup PGLPieGroup Pie and donuts charts
	\ingroup PGLObjectGroup
*/

/*! \brief A Pie Chart.

	A Pie Chart is a special graphical object since it has "no dimension" in the classical sense (in world coordinates).
	Hence, it is charaterized by normalized coordinates in the clipping region. The pie is described by:
	<ul>
	<li>a center (in normalized clipping coordinates),
	<li>a outside radius (in normalized clipping coordinates),
	<li>a inside radius (for donnut pie chart),
	<li>an exploded pie radius (in pixels),
	</ul>

	A data of the Pie is a CPGLPieData object that has to be allocated on the heap by the user. Since CPGLPieData is inherited
	from CPGLObject, this gives a total control on the Pie appearance, since each of its elements can be customized. 
	Note that all CPGLPieData are destroyed in the pie destructor.
  
	However, for simplicity, you can set automatic coloring and the color of the elements will be 
	chosen internaly (using the specified colormap). The alpha component is then determined by the alpha parameter of the 
	Pie (see SetAlpha)
 
	You can also modify the pie by adding an angle phase (counter clock wize in radians).
  \ingroup PGLPieGroup
*/
class PGLCORE_EXT_CLASS CPGLPie : public CPGLObject  
{
PGL_DECLARE_DYNCREATE(CPGLPie);
public:
	//! \name Constructors
	//@{
	//! Default constructor
	CPGLPie();
	//! Copy constructor
	CPGLPie(const CPGLPie& r){*this=r;};
	//! assignment constructor
	CPGLPie& operator = (const CPGLPie& r);
	//! Destructor
	virtual ~CPGLPie() {	Clear();	};
	//@}


	//! \name Data handling and iterator
	//@{
	//! Adds data to front (must be allocated on the heap)
	void PushFront( CPGLPieDataPtr pPieData)	{	ASSERT(pPieData);	m_lDatas.push_front(pPieData);};
	//! Adds data to back (must be allocated on the heap)
	void PushBack( CPGLPieDataPtr pPieData)		{	ASSERT(pPieData);	m_lDatas.push_back(pPieData);};
	//! returns number of pie data
	size_t GetDataSize() const	{	return m_lDatas.size();};
	//! returns iterator pointing to begining of data list
	CPGLPieDataList::iterator GetBegin()		{	return m_lDatas.begin();};
	//! returns iterator pointing to end of data list
	CPGLPieDataList::iterator GetEnd()		{	return m_lDatas.end();};
	//! returns iterator pointing to begining of data list, const
	CPGLPieDataList::const_iterator GetBegin() const {	return m_lDatas.begin();};
	//! returns iterator pointing to end of data list, const
	CPGLPieDataList::const_iterator GetEnd() const	{	return m_lDatas.end();};
	//! Deletes all data objects
	void Clear();
	//! returns the sum of data objects
	double GetDataSum() const;
	//@}

	//! \name Layout
	//@{
	//! returns true if data serie color is automatic
	bool IsAutoColoring() const			{	return m_bAutoColoring;};
	//! return current colormap (used with automatic coloring)
	CPGLUtility::EColorMap GetColorMap() const				{	return m_eColorMap;};
	//! returns background alpha for autocoloring
	double GetAlpha() const									{	return m_dAlpha;};
	//! returns phase
	double GetPhase() const									{	return m_dPhase;};
	//! returns pie radius (in normalized clipping coordinates)
	double GetRadius() const								{	return m_dnRadius;};
	//! returns inside pie radius (in normalized clipping coordinates)
	double GetInsideRadius() const							{	return m_dnInRadius;};
	//! returns exploded radius (in pixels)
	double GetExplodedRadius() const						{	return m_dpExplodedRadius;};
	//! return center (in normalized clipping coordinates)
	const CPGLPointD& GetCenter() const						{	return m_pnCenter;};

	//! Enables/disables automatic coloring
	void SetAutoColoring( bool on = true )					{	m_bAutoColoring = on;};
	//! Sets colormap (used for autocoloring)
	void SetColorMap(CPGLUtility::EColorMap eColorMap)		{	m_eColorMap = eColorMap;};
	//! sets background alpha for autocoloring
	void SetAlpha(double _dAlpha)							{	m_dAlpha=__min(1, __max(0,_dAlpha));};
	//! Set initial phase
	void SetPhase( double dPhase )							{	m_dPhase = dPhase;};
	//! sets pie radius (in normalized clipping coordinates)
	void SetRadius(double dRadius)							{	m_dnRadius = __max(1e-2,__min(1,dRadius));};
	//! sets inside pie radius (in normalized clipping coordinates)
	void SetInsideRadius(double dInsideRadius)				{	m_dnInRadius = __max(0,__min(1,dInsideRadius));};
	//! sets exploded radius (in pixels)
	void SetExplodedRadiusPixel(double _dExplodedRadius)	{	m_dpExplodedRadius = _dExplodedRadius;};
	//! sets center (in normalized clipping coordinates)
	void SetCenter(const CPGLPointD& _pCenter)			{	m_pnCenter = _pCenter;};
	//@}

	//! \name Values
	//@{
	//! returns value text object
	CPGLText& GetValuesText()				{	return m_tValues;};
	//! returns value text object
	const CPGLText& GetValuesText() const	{	return m_tValues;};
	//@}

	//! \name Virtual override
	//@{
    //! returns the extent of the datas
    virtual void GetUnionExtent(gfxinterface::CGfxInterface& gfx, CPGLRectD& rExtent);
    ///virtual function to override in derived classes
    virtual void UpdateExtent(gfxinterface::CGfxInterface& gfx);
	//! Add object to legend
	void PushLinesTop(CPGLLegendPtr pLegend);

	//! adds context menu items...
	//virtual void AddContextMenuItems(CMenu* pMenu);
	//! adds the line property page to the property sheet dialog.
	//virtual void AddPropertyPage(CPropertySheet *pPropSheet);
	//! Main plotting function
	virtual void PlotGfx(gfxinterface::CGfxInterface& gfx);
	//@}

	//! \name Serialization and debugging
	//@{
	//! Serialize functions
	void SerializeXML(CPGLArchive& ar);

	//! Debuggin functions
	#ifdef _DEBUG
	    virtual void Dump( CDumpContext& dc ) const;
	    virtual void AssertValid() const;   
	#endif
	//@}
protected:
	//! \name Attributes
	//@{
	//! Automatic colors
	bool m_bAutoColoring;
	//! Alpha for auto coloring
	double m_dAlpha;
	//! Colormap
	CPGLUtility::EColorMap m_eColorMap;
	//! phase (counter clockwize
	double m_dPhase;
	//! Data values
	CPGLPieDataList m_lDatas;
	//! pie center
	CPGLPointD m_pnCenter;
	//! pie radius
	double m_dnRadius;
	//! inside pie radius
	double m_dnInRadius;
	//! explode distance ( in pixels )
	double m_dpExplodedRadius;
	//! Value text object
	CPGLText m_tValues;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLPie );

/*! \example pie.cpp
 Using Pie Charts.

\image html pie.png "Pie Chart"
*/

#endif // !defined(AFX_PGLPIE_H__8D63690A_E25F_4D15_B3C4_F7BFBDA15B34__INCLUDED_)
